package cn.bfay.lion.rest.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;
import cn.bfay.cache.redis.RedisKeyBuilder;
import cn.bfay.cache.redis.RedisTime;
import cn.bfay.cache.redis.RedisUtils;
import cn.bfay.lion.rest.annotation.Login;
import cn.bfay.lion.rest.error.RestBusinessError;
import cn.bfay.lion.rest.model.UserSession;
import cn.bfay.lion.rest.redis.RedisKeyTemplate;
import cn.bfay.web.exception.BizBaseException;
import cn.bfay.web.util.WebUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

/**
 * 登录拦截.
 *
 * @author wangjiannan
 */
@Component
public class LoginInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
        throws Exception {
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod handlerMethod = ((HandlerMethod) handler);
        if (handlerMethod.getMethod().getAnnotation(Login.class) == null
            && handlerMethod.getBeanType().getAnnotation(Login.class) == null) {
            return true;
        }
        String openid = WebUtils.getCookieValue(request, "openid");
        String accessToken = WebUtils.getCookieValue(request, "accessToken");
        if (StringUtils.isBlank(openid) || StringUtils.isBlank(accessToken)) {
            throw new BizBaseException(RestBusinessError.LOGIN_NEED_LOGIN);
        }
        String redisKey = RedisKeyBuilder.generateRedisKey(RedisKeyTemplate.SESSION_TEMPLATE, openid);
        UserSession userSession = RedisUtils.getValue(redisKey, UserSession.class);
        if (userSession == null) {
            throw new BizBaseException(RestBusinessError.LOGIN_NEED_LOGIN);
        }
        String session = userSession.getAccessToken();
        if (StringUtils.isBlank(session)) {
            throw new BizBaseException(RestBusinessError.LOGIN_NEED_LOGIN);
        }
        if (!accessToken.equals(session)) {
            throw new BizBaseException(RestBusinessError.LOGIN_NEED_LOGIN);
        }

        RedisUtils.expire(redisKey, RedisTime.DAY, TimeUnit.SECONDS);
        //会话过期时间设置为12小时
        WebUtils.setCookie(response, "openid", openid, 60 * 60 * 12);
        WebUtils.setCookie(response, "accessToken", accessToken, 60 * 60 * 12);

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
        throws Exception {

    }
}
